#region Imported Namespaces
using System;
using System.Collections;
using System.Data;
using System.Data.SqlClient;
using System.Text;

using BO = PHSRAG.Insight21.BusinessObjects;
using DataAccess = PHSRAG.Utility.DataAccess;
using ICachePolicy = PHSRAG.Insight21.Policy.ICachePolicy;

#endregion

namespace PHSRAG.Insight21.COI
{
	/// <summary>
	/// COIOrganizationCollection.
	/// </summary>
	public class COIOrganizationCollection : BO.BusinessObject
	{
		#region Constants
		private const string	COIOrganizationCollectionKey = "COIOrganizationCollection_6C3C04C6-FD2F-430a-9E7E-CA6A860F8ADC";
		private const string	FilteredDataTableName = "filtered";
		private const string	OriginalDataTableName = "original";
		private const bool	DefaultSortSequence = true;
		#endregion

		#region Instance Variables
		private ArrayList		coiOrganizationCollection = new ArrayList();
		private string			currentDataTableName = OriginalDataTableName;
		private bool			sortAscending = true;
		private string			sortColumn = "DateCreated";	// Keep this in sync with what the stored proc orders by.
		#endregion

		#region Constructor
		/// <summary>
		/// Initilize the base class with the specified cache policy.
		/// </summary>
		/// <param name="cachePolicy">Prevalent cache policy</param>
		public COIOrganizationCollection(ICachePolicy cachePolicy) : base(cachePolicy)
		{
		
		}
		#endregion

		#region Public Properties
		/// <summary>
		/// Get the key to be used in all caching operations for this instance of the object.
		/// </summary>
		public static string CacheKey	{ get { return COIOrganizationCollectionKey; } }
		
		/// <summary>
		/// Get the total number of agreements.
		/// </summary>
		public int Count
		{
			get 
			{
				return (DataContainer.Tables.Count == 0) ? 0 : 
					DataContainer.Tables[OriginalDataTableName].Rows.Count; 
			}
		}

		/// <summary>
		/// Get the sort sequence.
		/// </summary>
		public bool SortAscending
		{
			get { return sortAscending; }
		}

		/// <summary>
		/// Get the name of the sort column.
		/// </summary>
		public string SortColumn
		{
			get { return sortColumn; }
		}
		#endregion

		#region BusinessObject Methods
		/// <summary>
		/// Cache the current instance using the prevalent cache policy.
		/// </summary>
		public override void Cache()
		{
			CachePolicy.Cache(COIOrganizationCollectionKey, this);
		}

		/// <summary>
		/// Load the current instance with COIOrganization data for the current user.
		/// </summary>
		/// <param name="connectionString">Database connection string</param>
		/// <param name="args">No parameters are required</param>
		public override void Load(string connectionString, params object[] args)
		{
			try
			{
				coiOrganizationCollection.Clear();
				DataContainer = DataAccess.GetDataSet(connectionString, "GetCOIOrganizationsForReview");
			
				if (DataContainer.Tables.Count == 1)
				{
					DataContainer.Tables[0].TableName = OriginalDataTableName;
				}

				else 
					throw new Exception("Stored Procedure returned incorrect number of tables in resultset");
			}
			catch( Exception e)
			{
				throw new Exception("Failed to load COIOrganizationCollection.", e);
			}
		}

		/// <summary>
		/// Remove the current instance from the cache using the prevalent cache policy.
		/// </summary>
		public override void UnCache()
		{
			CachePolicy.UnCache(COIOrganizationCollectionKey);
		}

		#endregion

		#region Public methods
		/// <summary>
		/// Returns all the organizations starting with the specified name
		/// </summary>
		/// <param name="orgName">Name(starting letters) of the organization to search</param>
		/// <returns>A table holding the search results</returns>
		public static DataTable GetOrganizations(string orgName)
		{
			try
			{
				return DataAccess.GetDataTable(Utility.DataAccess.ConnectionString, "GetCOIOrganizations",
						Utility.DataAccess.BuildSqlParameterArray("@orgName" ,SqlDbType.VarChar, orgName));
			}
			catch( Exception e)
			{
				throw new Exception("Failed to load GetOrganizations starting with the specified name.", e);
			}
		}
		
		
		/// <summary>
		/// Get the list of COIOrganization objects bound by a start and end index. These indices are in the list
		/// loaded during the Load() method into the data container. Typically, the start index
		/// is on a "page" boundary, where the "page" refers to a datagrid page.
		/// Note that the total number of objects returned may be less than the requested count.
		/// </summary>
		/// <param name="startIndex">Index within the list to begin</param>
		/// <param name="count">Total number of objects to load</param>
		/// <returns>Array list of COIOrganization objects</returns>
		public ArrayList GetCOIOrganizationList(int startIndex, int count)
		{
			try
			{
				ArrayList organizationList = new ArrayList();
				DataTable dt = DataContainer.Tables[currentDataTableName]; 
				int rowCount = dt.Rows.Count;
				for (int i = startIndex, end = Math.Min(i + count, rowCount); i < end; ++i)
				{
					organizationList.Add(new COIOrganization(CachePolicy, dt.Rows[i]));						
				}	
				return organizationList;
			}
			catch(Exception ex)
			{
				throw new Exception("Failed to get the entity list.", ex);
			}
		}

		/// <summary>
		/// Sort the list on a specified column.
		/// If the column to be sorted is the same as what was last sorted on, the sort sequence is toggled. 
		/// Else, the sort sequence is set to ascending.
		/// </summary>
		/// <param name="columnName">Column to sort on</param>
		public void Sort(string columnName)
		{			
			sortAscending = (sortColumn == columnName) ? !sortAscending : DefaultSortSequence;
			sortColumn = columnName;

			DataTable dataTable = DataContainer.Tables[currentDataTableName];
			DataView dataView = dataTable.DefaultView;
			dataView.Sort = string.Format("{0} {1}", columnName, sortAscending ? "ASC" : "DESC");

			DataTable sortedDataTable = dataTable.Clone();
			foreach (DataRowView rowView in dataView)
			{
				sortedDataTable.ImportRow(rowView.Row);
			}
			DataContainer.Tables.Remove(currentDataTableName);
			DataContainer.Tables.Add(sortedDataTable);
			DataContainer.Tables[0].TableName=currentDataTableName;
		}
		#endregion
	}
}
